package cn.gs.common;

import cn.gs.common.config.CommonSetting;
import cn.gs.common.config.ServerConfig;
import cn.gs.common.config.ServerConfigGroup;
import cn.gs.common.implement.CommandExecuter;
import cn.gs.util.ObjectToXMLUtil;
import java.io.File;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.text.MessageFormat;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * @author gs
 */
public class CommonMain {

    private ServerConfigGroup servers;
    private CommandExecuter commandExecuter;
    private ServerConfig serverConfig;
    private CommonSetting setting;
    public static final Random random = new Random();
    public static final CommonMain commonMain = new CommonMain();

    public boolean init(String serverName) {
        boolean flag = true;
        flag &= initCommonSetting(serverName);
        if (!flag) {
            return flag;
        }
        flag &= initServerConfigGroup(serverName);
        if (!flag) {
            return flag;
        }
        flag &= initCommandExecuter(serverName);
        return flag;
    }

    private boolean initCommonSetting(String serverName) {
        ObjectToXMLUtil util = new ObjectToXMLUtil();
        File file = new File("set.xml");
        if (file.exists()) {
            setting = (CommonSetting) util.objectXmlDecoder(file.getAbsolutePath());
            Logger.getLogger(this.getClass().getName()).log(Level.INFO, serverName + " Setting loaded successed.");
            return true;
        }
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, serverName + " Start Failed by Setting File lost.");
        return false;
    }

    private boolean initCommandExecuter(String serverName) {
        try {
            commandExecuter = new CommandExecuter();
            commandExecuter.put("common", this);
        } catch (RemoteException ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, serverName + " Start Failed by CommandExecuter Exception.", ex);
            return false;
        }
        setServerConfig(servers.getServers().get(serverName));
        if (getServerConfig() == null) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, serverName + " Start Failed by Config File lost.");
            return false;
        }
        try {
            LocateRegistry.createRegistry(getServerConfig().getPort());
            String uri = MessageFormat.format("//{0}:{1}/{2}Script", getServerConfig().getIp(), String.valueOf(getServerConfig().getPort()), serverName);
            Naming.rebind(uri, commandExecuter);
            Logger.getLogger(this.getClass().getName()).log(Level.INFO, serverName + " script started successed. " + uri);
        } catch (RemoteException | MalformedURLException ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, serverName + " Start Failed by Port Exception.", ex);
            return false;
        }
        return true;
    }

    private boolean initServerConfigGroup(String serverName) {
        ObjectToXMLUtil util = new ObjectToXMLUtil();
        File file = new File("conf.xml");
        if (file.exists()) {
            try {
                servers = (ServerConfigGroup) util.objectXmlDecoder(file.getAbsolutePath());
                Logger.getLogger(this.getClass().getName()).log(Level.INFO, serverName + " ServerConfig loaded successed.");
                return true;
            } catch (Throwable ex) {
                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, serverName + " Start Failed by ServerConfig Exception.", ex);
                return false;
            }
        }
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, serverName + " Start Failed by ServerConfig File lost.");
        return false;
    }

    public CommandExecuter getCommandExecuter() {
        return commandExecuter;
    }

    public void setCommandExecuter(CommandExecuter commandExecuter) {
        this.commandExecuter = commandExecuter;
    }

    public ServerConfig getServerConfig() {
        return serverConfig;
    }

    public void setServerConfig(ServerConfig serverConfig) {
        this.serverConfig = serverConfig;
    }

    public ServerConfigGroup getServers() {
        return servers;
    }

    public void setServers(ServerConfigGroup servers) {
        this.servers = servers;
    }

    public CommonSetting getSetting() {
        return setting;
    }

    public void setSetting(CommonSetting setting) {
        this.setting = setting;
    }
}
